package com.settlement.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.settlement.system.common.constant.SystemConstants;
import com.settlement.system.common.enums.StoreStatusEnum;
import com.settlement.system.common.model.Option;
import com.settlement.system.common.util.SimpleEncryptHelper;
import com.settlement.system.mapper.SysStoreAccountMapper;
import com.settlement.system.model.entity.SysStore;
import com.settlement.system.model.entity.SysStoreAccount;
import com.settlement.system.model.form.StoreAccountForm;
import com.settlement.system.model.query.StoreAccountPageQuery;
import com.settlement.system.model.vo.StoreAccountSyncVo;
import com.settlement.system.service.SysDictTypeService;
import com.settlement.system.service.SysStoreAccountService;
import com.settlement.system.service.SysStoreService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 店铺账号表 服务实现类
 * </p>
 *
 * @author huangrensen
 * @since 2023-08-25
 */
@Service
@RequiredArgsConstructor
public class SysStoreAccountServiceImpl extends ServiceImpl<SysStoreAccountMapper, SysStoreAccount> implements SysStoreAccountService {

    private final SysDictTypeService dictTypeService;
    private final SysStoreService storeService;

    private final RedisTemplate redisTemplate;

    @Override
    public Page<SysStoreAccount> getStoreAccountPage(StoreAccountPageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();
        // 查询数据
        Page<SysStoreAccount> storePage = this.page(new Page<>(pageNum, pageSize), new LambdaQueryWrapper<SysStoreAccount>().like(StrUtil.isNotBlank(keywords), SysStoreAccount::getCommercePlatformStoreCode, keywords).or().like(StrUtil.isNotBlank(keywords), SysStoreAccount::getAccount, keywords));
        // 转换数据字典和店铺名称
        List<SysStoreAccount> accountList = storePage.getRecords();
        if (accountList.size() > 0) {
            List<Option> platformOptionList = dictTypeService.listDictItemsByTypeCode(SystemConstants.PLATFORM_KEY);
            // 根据店铺编码查出所有店铺
            Set<String> codeList = accountList.stream().map(SysStoreAccount::getCommercePlatformStoreCode).collect(Collectors.toSet());
            List<SysStore> sysStores = storeService.getBaseMapper().selectList(new LambdaQueryWrapper<SysStore>().in(SysStore::getCommercePlatformStoreCode, codeList));
            for (SysStoreAccount sysStoreAccount : accountList) {
                sysStoreAccount.setCommercePlatformStoreName(sysStores.stream().filter(store -> store.getCommercePlatformStoreCode().equals(sysStoreAccount.getCommercePlatformStoreCode())).findFirst().map(SysStore::getCommercePlatformStoreName).orElse(null));
                sysStores.stream().filter(sysStore -> sysStore.getCommercePlatformStoreCode().equals(sysStoreAccount.getCommercePlatformStoreCode())).findFirst().ifPresent(store -> sysStoreAccount.setPlatformName(platformOptionList.stream().filter(option -> option.getValue().equals(store.getStoreKey())).findFirst().map(Option::getLabel).orElse(null)));
            }
        }
        return storePage;
    }

    @Override
    public SysStoreAccount getStoreAccountFormData(Long storeAccountId) {
        return this.baseMapper.selectById(storeAccountId);
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean saveStoreAccount(StoreAccountForm storeAccountForm) {
        // 去重空格
        storeAccountForm.setVoucher(storeAccountForm.getVoucher().strip());
        // 实体转换 form->entity
        SysStoreAccount store = new SysStoreAccount();
        BeanUtil.copyProperties(storeAccountForm, store);
        if(StringUtils.hasText(storeAccountForm.getMobile())){
            Assert.isTrue(storeAccountForm.getMobile().length() == 11, "手机号格式错误");
        }
        // 凭证Key不能重复
        if(Objects.isNull(storeAccountForm.getId())){
            List<SysStoreAccount> list = this.list(new LambdaQueryWrapper<SysStoreAccount>().eq(SysStoreAccount::getVoucher, store.getVoucher()));
            Assert.isTrue(list.size() == 0, "凭证Key【%s】重复".formatted(store.getVoucher()));
        }else{
            List<SysStoreAccount> list = this.list(new LambdaQueryWrapper<SysStoreAccount>().eq(SysStoreAccount::getVoucher, store.getVoucher()).ne(SysStoreAccount::getId, store.getId()));
            Assert.isTrue(list.size() == 0, "凭证Key【%s】重复".formatted(store.getVoucher()));
        }
        redisTemplate.delete(SystemConstants.STORE_ACCOUNT_PREFIX + store.getId());
        return saveOrUpdate(store);
    }

    @Override
    @SuppressWarnings("unchecked")
    public boolean deleteStoreAccounts(String idsStr) {
        Assert.isTrue(StrUtil.isNotBlank(idsStr), "删除的店铺账号数据为空");
        List<Long> ids = Arrays.stream(idsStr.split(",")).map(Long::parseLong).collect(Collectors.toList());
        List<SysStoreAccount> list = this.list(new LambdaQueryWrapper<SysStoreAccount>().in(SysStoreAccount::getId, ids));
        for (SysStoreAccount storeAccount : list) {
            redisTemplate.delete(SystemConstants.STORE_ACCOUNT_PREFIX + storeAccount.getId());
        }
        return this.removeByIds(ids);
    }

    @Override
    @SuppressWarnings("unchecked")
    public SysStoreAccount getById(Long storeAccountId) {
        Object value = redisTemplate.opsForValue().get(SystemConstants.STORE_ACCOUNT_PREFIX + storeAccountId);
        if (value != null) {
            return (SysStoreAccount) value;
        }
        SysStoreAccount storeAccount = this.baseMapper.selectById(storeAccountId);
        redisTemplate.opsForValue().set(SystemConstants.STORE_ACCOUNT_PREFIX + storeAccountId, storeAccount, 1,
                TimeUnit.HOURS);
        return storeAccount;
    }

    @Override
    public List<SysStoreAccount> getAccountList(String platform, String type) {
        List<SysStore> sysStores = storeService.list(new LambdaQueryWrapper<SysStore>().eq(SysStore::getStoreKey, platform));
        List<String> storeKeys = sysStores.stream().map(SysStore::getCommercePlatformStoreCode).filter(StringUtils::hasText).toList();
        List<SysStoreAccount> sysStoreAccountList = this.list(new LambdaQueryWrapper<SysStoreAccount>().eq(SysStoreAccount::getAccountType, type.toLowerCase()
        ).in(SysStoreAccount::getCommercePlatformStoreCode,
                storeKeys));
        // 过滤已禁用的店铺
        for (SysStore sysStore : sysStores) {
            if(Objects.equals(sysStore.getStatus(), StoreStatusEnum.DISABLE.getValue())){
                sysStoreAccountList.removeIf(item -> Objects.equals(item.getCommercePlatformStoreCode(), sysStore.getCommercePlatformStoreCode()));
            }
        }
        for (SysStoreAccount storeAccount : sysStoreAccountList) {
            sysStores.stream().filter(sysStore -> sysStore.getCommercePlatformStoreCode().equals(storeAccount.getCommercePlatformStoreCode()))
                    .findFirst()
                    .ifPresent(sysStore -> {
                        storeAccount.setPlatformStoreName(sysStore.getCommercePlatformStoreName());
                        storeAccount.setStoreKey(sysStore.getStoreKey());
                        storeAccount.setStoreCode(sysStore.getCommercePlatformStoreCode());
                        storeAccount.setStoreId(sysStore.getId());
                    });
            // 解密账号和密码
            if (StringUtils.hasText(storeAccount.getUserName())) {
                storeAccount.setUserName(SimpleEncryptHelper.decode(storeAccount.getUserName()));
            }
            if (StringUtils.hasText(storeAccount.getPwd())) {
                storeAccount.setPwd(SimpleEncryptHelper.decode(storeAccount.getPwd()));
            }
        }
        return sysStoreAccountList;
    }

    @Override
    public void sync(List<StoreAccountSyncVo> syncVoList) {
        List<String> voucherList = syncVoList.stream().map(StoreAccountSyncVo::getVoucher).distinct().toList();
        if (voucherList.size() == 0) {
            return;
        }
        List<SysStoreAccount> storeAccountList = this.list(new LambdaQueryWrapper<SysStoreAccount>().in(SysStoreAccount::getVoucher, voucherList));
        StoreAccountSyncVo syncVo;
        for (SysStoreAccount storeAccount : storeAccountList) {
            syncVo = syncVoList.stream().filter(item -> Objects.equals(item.getVoucher(), storeAccount.getVoucher())).findFirst().orElse(null);
            if(Objects.nonNull(syncVo)){
                // 加密账号密码
                storeAccount.setUserName(SimpleEncryptHelper.encode(syncVo.getUserName()));
                storeAccount.setPwd(SimpleEncryptHelper.encode(syncVo.getPwd()));
            }
        }
        this.updateBatchById(storeAccountList);
    }
}
